import {
  BadRequestException,
  Controller,
  Post,
  Req,
  Res,
  Get,
  Body,
  UploadedFile,
  UseInterceptors,
} from '@nestjs/common';
import {
  ApiBody,
  ApiConsumes,
  ApiOperation,
  ApiTags,
  ApiBearerAuth,
  ApiQuery,
} from '@nestjs/swagger';
import { FileInterceptor } from '@nestjs/platform-express';
import { Public } from '~/common/decorators/public.decorator';
import { FileNameEncodePipe } from '~/common/pipes/file-name-encode.pipe';
import { deleteFile } from '~/utils';

import { ApiSecurityAuth } from '~/common/decorators/swagger.decorator';

import {
  FileUploadDto,
  FileUploadChunkDto,
  FileUploadChunkMergeDto,
  FileUploadChunkCheckDto,
  FileDownLoadChunkDto,
} from './upload.dto';
import { UploadService } from './upload.service';
import { SkipThrottle } from '@nestjs/throttler';

@ApiSecurityAuth()
@ApiTags('Tools - 上传模块')
@Controller('upload')
@Public()
export class UploadController {
  constructor(private uploadService: UploadService) {}

  @Post('single')
  @ApiOperation({ summary: '上传' })
  @ApiConsumes('multipart/form-data')
  @ApiBearerAuth()
  @UseInterceptors(FileInterceptor('file'))
  @ApiBody({
    type: FileUploadDto,
  })
  async upload(
    @UploadedFile(new FileNameEncodePipe()) file: Express.Multer.File,
  ) {
    try {
      const path = await this.uploadService.saveFile(file);
      return {
        filename: path,
      };
    } catch (error) {
      console.log(error);
      throw new BadRequestException('上传失败');
    }
  }

  @Post('chunk')
  @SkipThrottle()
  @ApiOperation({ summary: '切片上传' })
  @ApiConsumes('multipart/form-data')
  @ApiBearerAuth()
  @UseInterceptors(FileInterceptor('chunk'))
  @ApiBody({
    type: FileUploadChunkDto,
  })
  async uploadChunk(@UploadedFile() chunk: Express.Multer.File, @Req() req) {
    return await this.uploadService.saveChunk(chunk, req);
  }

  @Post('merge')
  @ApiOperation({
    summary: '合并切片',
  })
  @ApiBody({
    type: FileUploadChunkMergeDto,
  })
  async uploadChunkMerge(@Req() req: FileUploadChunkMergeDto) {
    return this.uploadService.uploadChunkMerge(req);
  }

  /* 检查已上传文件或者切片 */
  @Get('check')
  @ApiOperation({
    summary: '检查切片',
  })
  @ApiQuery({
    type: FileUploadChunkCheckDto,
  })
  async checkChunks(@Req() req: FileUploadChunkCheckDto) {
    return this.uploadService.checkChunks(req);
  }

  @Get('file-chunk')
  @ApiOperation({
    summary: '切片下载',
  })
  @SkipThrottle()
  @ApiQuery({
    type: FileDownLoadChunkDto,
  })
  async downChunks(@Req() req: FileDownLoadChunkDto, @Res() res) {
    return this.uploadService.downChunks(req, res);
  }

  @Post('delete-file')
  @ApiOperation({ summary: '根据文件路径删除文件' })
  deleteFileByPath(@Body('path') path: string) {
    if (path !== '') {
      deleteFile(path);
    }
    return {
      msg: '删除成功',
    };
  }
}
